package opengraph.api

class OpenGraphMeta(var content: MutableList<String> = mutableListOf()) : HashMap<String, OpenGraphMeta>() {
    companion object {

        //这里用 @og 固定表示og标签 因为命名空间是可以任意命名的
        const val OG_TAG_VAR = "@og"
    }
    fun getOrCreate(key: String): OpenGraphMeta {
        val def = super.get(key) ?: run {
            val defaultValue = OpenGraphMeta()
            put(key, defaultValue)
            defaultValue
        }
        return def
    }

    override fun toString(): String {
        if (size == 0) {
            return content.toString()
        }
        return buildString {
            append("{")
            if (content.isNotEmpty()) {
                append("content = $content, ")
            }
            entries.forEachIndexed { index, entry ->
                append("${entry.key} = ${entry.value}")
                if (entries.size - 1 != index) {
                    append(", ")
                }
            }
            append("}")
        }
    }



    fun <T> find(path:String): T? {
        if(path.isEmpty()) {
            return null
        }
        var meta: OpenGraphMeta? = this
        val paths = path.split(".")
            .map{
                return@map it.trim().apply { require(isNotEmpty()){"Path cannot be empty."} }
            }
        paths.forEachIndexed { index, cmds ->
            if(index == paths.size - 1){
                meta?:return null
                //$og.url:{number}
                //获取url的值数组或者指定index
                if(cmds.contains(":")){
                    val cmd = cmds.split(":").map(String::trim)
                    require(cmd.size == 2){"Unsupported command."}
                    val lastMeta = meta!![cmd[0]]
                    lastMeta?:return null
                    val contentIndex = cmd[1].toIntOrNull()
                    if(contentIndex == null){
                        return lastMeta.content as T
                    }
                    return lastMeta.content[contentIndex] as T
                }
                return meta!![cmds] as T
            } else {
                meta = get(cmds)
            }
        }


        return null
    }
}